home *** CD-ROM | disk | FTP | other *** search
/ SIGGRAPH 2002: Conference Proceedings / SIGGRAPH 2002: Conference Proceedings.iso / pc / supplemental_material / kalnins / paper-effect.txt
Text File  |  2002-05-10  |  4KB  |  115 lines

  1. // Register Combiner Program for media simulation in WYSISYG NPR
  2. // =============================================================
  3. //
  4. // This program implements the "paper effect" algorithm described in:
  5. //
  6. //    WYSIWYG NPR: Drawing Strokes Directly on 3D Models.
  7. //    by Robert D. Kalnins, Lee Markosian, Barbara J. Meier,
  8. //    Michael A. Kowalski, Joseph C. Lee, Philip L. Davidson,
  9. //    Matthew Webb, John F. Hughes and Adam Finkelstein.
  10. //    SIGGRAPH 2002.
  11. //
  12. // The pixel's incoming color (p) and alpha (a) are derived as a
  13. // 'GL_MODULATE' of Texture0 and Primary Color.  The outgoing color
  14. // (p') is simply p (unchanged). Howver, outgoing alpha (a') is
  15. // computed as a' = t(h,a), where h is the 'height' of the paper
  16. // (Texture1 alpha channel), and t(h,a) is described both below and
  17. // in the paper.  Typically, the Texture1 UV coordinate of the
  18. // incoming fragment is derived from its screen-space position, so
  19. // that the paper texture can be thought of as a media surface fixed
  20. // to the viewing window. This can be achieved by a trivial vertex
  21. // program that accounts for hardware perspective correction.
  22. //
  23. // For convenience, the user can adjust the 'brightness' (b) and
  24. // 'contrast' (c) of the paper texture using methods taken from:
  25. //
  26. //   P. Haeberli, D. Voorhies.
  27. //   Image Processing by Linear Interpolation and Extrapolation.
  28. //   Iris Universe, (28):8-9, 1994.
  29. //   http://www.sgi.com/grafica/interp/
  30. //
  31. // Both b and c are in [0,1], with value 0.5 causing no effect.
  32. //
  33. // In terms of the notation in the reference:
  34. //
  35. //    alpha = 2b or 2c and mean luminance is 0.5
  36. //
  37. // In terms of the program below, b & c map h to h' as
  38. //
  39. //    h' = (0.5 - c) + (2c)(2b)h
  40. //
  41. // Register Combiner Program comments:
  42. //
  43. //   Tex0 binds stroke or object texture (generally in RGBA channels)
  44. //   and this program performs GL_MODULATE (Tex0 * Col0) to give
  45. //   incoming pigment color (p) and alpha (a)
  46. //
  47. //   Tex1 binds paper height (h) (in the alpha channel -- mean height 0.5)
  48. //
  49. // As described in the paper, we use transfer functions to remap alpha:
  50. //     peak(a) = clamp(2a)
  51. //   valley(a) = clamp(2a - 1)
  52. //      t(h,a) = peak(a)h + valley(a)(1 - h)
  53. //
  54. // The final combiner outputs:
  55. //    color p' = p
  56. //    alpha a' = t(h',a)
  57. //
  58. // Stage 0:
  59. //    RGB: (Alpha computation in BLUE channel)
  60. //       Spare1[B] = h' = (0.5 - c) + (2c)(2b)h
  61. //    Alpha:
  62. //       a = Col0*Tex0
  63. //       Spare0[A] = peak(a)
  64. //       Spare1[A] = valley(a)
  65. // Stage 1:
  66. //    RGB:
  67. //       Spare0'[RGB] = p = Col0*Tex0
  68. //    Alpha:
  69. //       Spare0'[A] = a' =         h'*   peak(a) +        (1-h') * valley(a)
  70. //                       = Spare1[B] * Spare0[A] + (1-Spare1[B]) * Spare1[A]
  71. // Final:
  72. //    Output[RGB] = p' = p      = Spare0'[RGB]
  73. //    Output[A]   = a' = t(h,a) = Spare0'[A]
  74. //
  75. // Note: register combiner Const1 must hold 2bc, but this must be
  76. // clamped to [0,1]. So, if b > 0.5, the product is remapped into [0,1]
  77. // as below. The end result is that if c,b > 0.5, the effect of b is
  78. // diminished...
  79.  
  80. CONSTRAST = c;
  81. TWO_X_CONTRAST_X_BRIGHTNESS = (b<=0.5)?(2.0*c*b):(c+(1.0-c)*(b-0.5)/0.5);
  82.  
  83. // **begin** nvparse Register Combiner Program string
  84. !!RC1.0
  85. const0 = (0.000000, 0.000000, 0.000000, CONTRAST                   );
  86. const1 = (0.000000, 0.000000, 0.000000, TWO_X_CONTRAST_X_BRIGHTNESS);
  87. {
  88.    rgb {
  89.       discard = -half_bias(const0.a) * -half_bias(zero.a);
  90.       discard =   unsigned(const1.a) *   unsigned(tex1.a);
  91.       spare1  = sum();
  92.       scale_by_two();
  93.    }
  94.    alpha {
  95.       spare0 =         unsigned(col0) *  unsigned(tex0);
  96.       discard = unsigned_invert(zero) * half_bias(zero);
  97.       spare1  = sum();
  98.       scale_by_two();
  99.    }
  100. }
  101. {
  102.    rgb {
  103.       spare0 =    unsigned(col0) * unsigned(tex0);
  104.    }
  105.    alpha {
  106.       discard = unsigned(spare0) *        unsigned(spare1.b);
  107.       discard = unsigned(spare1) * unsigned_invert(spare1.b);
  108.       spare0  = sum();
  109.    }
  110. }
  111. out.rgb = spare0;
  112. out.a   = spare0;
  113.  
  114. // **end** nvparse Register Combiner Program string
  115.